﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;
using System.Xml;

namespace ExtractFiles
{
    static class SearchHelper
    {
        private static ArrayList searchFiles(string searchDirectoryPath, string filesToSearchSourcePath, string filter)
        {
            try
            {
                string[] dirs = Directory.GetFiles(searchDirectoryPath, filter, SearchOption.AllDirectories);
                string[] filesToSearch = FileHelper.ReadFromFile(filesToSearchSourcePath);
                ArrayList results = new ArrayList();
                foreach (string dir in dirs)
                {
                    string[] splitted = dir.Split('\\');
                    string filename = splitted[splitted.Length - 1];
                    if (filesToSearch.Any(file => file.CompareTo(filename) == 0))
                    {
                        results.Add(dir);
                    }
                }
                return results;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public static ArrayList SearchFiles(string searchDirectoryPath, string filesToSearchSourcePath, string[] filters)
        {
            ArrayList results = new ArrayList();
            foreach (string filter in filters)
            {
                ArrayList result = searchFiles(searchDirectoryPath, filesToSearchSourcePath, filter.Trim());
                foreach (string res in result)
                {
                    results.Add(res);
                }
            }
            return results;
        }

        public static string[] ProcessSearchXMLFiles(string sourcePath, string[] patterns, string searchBy, string[] searchStrings, string outputPath)
        {
            string[] files = Directory.GetFiles(sourcePath, "*.xml", SearchOption.AllDirectories);
            string[] pairs = new string[Int16.MaxValue];
            foreach (string file in files)
            {
                string filename = file.Substring(Directory.GetParent(file).FullName.Length + 1);
                filename = filename.Substring(0, filename.Length - 4);
                XmlDocument doc = new XmlDocument();
                doc.Load(file);
                if (searchBy.Equals("tagname"))
                {
                    pairs = searchXmlByTagName(files, searchStrings, patterns);
                }
                else
                {
                    pairs = searchXmlById(files, searchStrings, patterns);
                }
            }
            try
            {
                if (outputPath.EndsWith(".txt"))
                {
                    FileHelper.WriteToTextUnique(outputPath, pairs.Distinct().ToArray());
                }
                else if (outputPath.EndsWith(".xls") || outputPath.EndsWith(".xlsx"))
                {
                    FileHelper.WriteToExcelUnique(outputPath, pairs.Distinct().ToArray());
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return pairs;
        }

        private static string[] searchXmlByTagName(string[] files, string[] searchStrings, string[] patterns)
        {
            string[] pairs = new string[Int16.MaxValue];
            int count = 0;
            foreach (string file in files)
            {
                string filename = file.Substring(Directory.GetParent(file).FullName.Length + 1);
                filename = filename.Substring(0, filename.Length - 4);
                XmlDocument doc = new XmlDocument();
                doc.Load(file);
                foreach (string searchStr in searchStrings)
                {
                    XmlNodeList list = doc.GetElementsByTagName(searchStr.Trim());
                    foreach (XmlNode node in list)
                    {
                        foreach (string pattern in patterns)
                        {
                            if (!node.InnerXml.Equals(""))
                            {
                                if (node.InnerXml.Contains(pattern.Trim()))
                                {
                                    pairs[count] = filename + "/" + node.InnerXml;
                                    count++;
                                    break;
                                }
                            }
                            else
                            {
                                pairs[count] = filename + "/NA";
                                count++;
                                break;
                            }
                        }
                    }
                }
            }
            return pairs;
        }

        private static string[] searchXmlById(string[] files, string[] searchIds, string[] patterns)
        {
            string[] pairs = new string[Int16.MaxValue];
            int count = 0;
            foreach (string file in files)
            {
                string filename = file.Substring(Directory.GetParent(file).FullName.Length + 1);
                filename = filename.Substring(0, filename.Length - 4);
                XmlDocument doc = new XmlDocument();
                doc.Load(file);
                foreach (string searchStr in searchIds)
                {
                    XmlElement node = doc.GetElementById(searchStr);
                    if (node != null)
                    {
                        foreach (string pattern in patterns)
                        {
                            if (node.InnerXml.Contains(pattern.Trim()))
                            {
                                pairs[count] = filename + "/" + node.InnerXml;
                                count++;
                                break;
                            }
                        }
                    }
                    else
                    {
                        pairs[count] = filename + "/NA";
                        count++;
                        break;
                    }
                }
            }
            return pairs;
        }

        public static string[] ProcessSearchTXTFiles(string sourcePath, string[] patterns, string outputPath)
        {
            string[] files = Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories);
            string[] pairs = new string[Int16.MaxValue];
            int count = 0;
            foreach (string file in files)
            {
                string filename = file.Substring(Directory.GetParent(file).FullName.Length + 1);
                filename = filename.Substring(0, filename.Length - 4);
                string[] lines = File.ReadAllLines(file);
                for (int lineNo = 1; lineNo <= lines.Length; lineNo++)
                {
                    foreach (string pattern in patterns)
                    {
                        if (lines[lineNo - 1].Contains(pattern.Trim()))
                        {
                            pairs[count] = filename + "/line " + lineNo.ToString();
                            count++;
                        }
                    }
                }
            }
            try
            {
                if (outputPath.EndsWith(".txt"))
                {
                    FileHelper.WriteToTextUnique(outputPath, pairs.Distinct().ToArray());
                }
                else if (outputPath.EndsWith(".xls") || outputPath.EndsWith(".xlsx"))
                {
                    FileHelper.WriteToExcelUnique(outputPath, pairs.Distinct().ToArray());
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return pairs;
        }
    }
}
